package com.demon.androidbasic.dialog

import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.content.Context
import android.content.DialogInterface
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.util.SparseArray
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.annotation.*
import androidx.appcompat.app.AppCompatDialog
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import com.demon.androidbasic.R
import com.demon.androidbasic.action.*
import java.lang.ref.SoftReference
import java.util.*

/**
 * author : Android 轮子哥
 * github : https://github.com/getActivity/AndroidProject
 * time   : 2018/11/24
 * desc   : Dialog 基类
 */
class BaseDialog(
    private val myContext: Context,
    @StyleRes themeResId: Int = R.style.BaseDialogStyle
) :
    AppCompatDialog(myContext, themeResId), LifecycleOwner,
    HandlerAction, AnimAction, DialogInterface.OnShowListener,
    DialogInterface.OnCancelListener, DialogInterface.OnDismissListener {
    private val mListeners = ListenersWrapper(this)
    private val mLifecycle = LifecycleRegistry(this)
    private var mShowListeners: MutableList<OnShowListener?>? = null
    private var mCancelListeners: MutableList<OnCancelListener?>? = null
    private var mDismissListeners: MutableList<OnDismissListener?>? = null

    /**
     * 获取 Dialog 的根布局
     */
    val contentView: View?
        get() = findViewById(Window.ID_ANDROID_CONTENT)
    /**
     * 获取当前设置重心
     */
    /**
     * 设置 Dialog 重心
     */
    var gravity: Int
        get() {
            val window = window
            if (window != null) {
                val params = window.attributes
                return params.gravity
            }
            return Gravity.NO_GRAVITY
        }
        set(gravity) {
            val window = window
            window?.setGravity(gravity)
        }

    /**
     * 设置宽度
     */
    fun setWidth(width: Int) {
        val window = window
        if (window != null) {
            val params = window.attributes
            params.width = width
            window.attributes = params
        }
    }

    /**
     * 设置高度
     */
    fun setHeight(height: Int) {
        val window = window
        if (window != null) {
            val params = window.attributes
            params.height = height
            window.attributes = params
        }
    }
    /**
     * 获取 Dialog 的动画
     */
    /**
     * 设置 Dialog 的动画
     */
    var windowAnimations: Int
        get() {
            val window = window
            return if (window != null) {
                window.attributes.windowAnimations
            } else AnimAction.Companion.ANIM_DEFAULT
        }
        set(id) {
            val window = window
            window?.setWindowAnimations(id)
        }

    /**
     * 设置背景遮盖层开关
     */
    fun setBackgroundDimEnabled(enabled: Boolean) {
        val window = window
        if (window != null) {
            if (enabled) {
                window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
            } else {
                window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
            }
        }
    }

    /**
     * 设置背景遮盖层的透明度（前提条件是背景遮盖层开关必须是为开启状态）
     */
    fun setBackgroundDimAmount(@FloatRange(from = 0.0, to = 1.0) dimAmount: Float) {
        val window = window
        window?.setDimAmount(dimAmount)
    }

    override fun dismiss() {
        removeCallbacks()
        val focusView = currentFocus
        if (focusView != null) {
            ContextCompat.getSystemService(myContext, InputMethodManager::class.java)!!
                .hideSoftInputFromWindow(
                    focusView.windowToken,
                    0
                )
        }
        super.dismiss()
    }

    override fun getLifecycle(): Lifecycle {
        return mLifecycle
    }

    /**
     * 设置一个显示监听器
     *
     * @param listener       显示监听器对象
     */
    @Deprecated("请使用 {@link #addOnShowListener(BaseDialog.OnShowListener)}}")
    override fun setOnShowListener(listener: DialogInterface.OnShowListener?) {
        if (listener == null) {
            return
        }
        addOnShowListener(ShowListenerWrapper(listener))
    }

    /**
     * 设置一个取消监听器
     *
     * @param listener       取消监听器对象
     */
    @Deprecated("请使用 {@link #addOnCancelListener(BaseDialog.OnCancelListener)}")
    override fun setOnCancelListener(listener: DialogInterface.OnCancelListener?) {
        if (listener == null) {
            return
        }
        addOnCancelListener(CancelListenerWrapper(listener))
    }

    /**
     * 设置一个销毁监听器
     *
     * @param listener       销毁监听器对象
     */
    @Deprecated("请使用 {@link #addOnDismissListener(BaseDialog.OnDismissListener)}")
    override fun setOnDismissListener(listener: DialogInterface.OnDismissListener?) {
        if (listener == null) {
            return
        }
        addOnDismissListener(DismissListenerWrapper(listener))
    }

    /**
     * 设置一个按键监听器
     *
     * @param listener       按键监听器对象
     */
    @Deprecated("请使用 {@link #setOnKeyListener(BaseDialog.OnKeyListener)}")
    override fun setOnKeyListener(listener: DialogInterface.OnKeyListener?) {
        super.setOnKeyListener(listener)
    }

    fun setOnKeyListener(listener: OnKeyListener?) {
        super.setOnKeyListener(KeyListenerWrapper(listener))
    }

    /**
     * 添加一个显示监听器
     *
     * @param listener      监听器对象
     */
    fun addOnShowListener(listener: OnShowListener?) {
        if (mShowListeners == null) {
            mShowListeners = ArrayList()
            super.setOnShowListener(mListeners)
        }
        mShowListeners!!.add(listener)
    }

    /**
     * 添加一个取消监听器
     *
     * @param listener      监听器对象
     */
    fun addOnCancelListener(listener: OnCancelListener?) {
        if (mCancelListeners == null) {
            mCancelListeners = ArrayList()
            super.setOnCancelListener(mListeners)
        }
        mCancelListeners!!.add(listener)
    }

    /**
     * 添加一个销毁监听器
     *
     * @param listener      监听器对象
     */
    fun addOnDismissListener(listener: OnDismissListener?) {
        if (mDismissListeners == null) {
            mDismissListeners = ArrayList()
            super.setOnDismissListener(mListeners)
        }
        mDismissListeners!!.add(listener)
    }

    /**
     * 移除一个显示监听器
     *
     * @param listener      监听器对象
     */
    fun removeOnShowListener(listener: OnShowListener?) {
        if (mShowListeners != null) {
            mShowListeners!!.remove(listener)
        }
    }

    /**
     * 移除一个取消监听器
     *
     * @param listener      监听器对象
     */
    fun removeOnCancelListener(listener: OnCancelListener?) {
        if (mCancelListeners != null) {
            mCancelListeners!!.remove(listener)
        }
    }

    /**
     * 移除一个销毁监听器
     *
     * @param listener      监听器对象
     */
    fun removeOnDismissListener(listener: OnDismissListener?) {
        if (mDismissListeners != null) {
            mDismissListeners!!.remove(listener)
        }
    }

    /**
     * 设置显示监听器集合
     */
    private fun setOnShowListeners(listeners: MutableList<OnShowListener?>?) {
        super.setOnShowListener(mListeners)
        mShowListeners = listeners
    }

    /**
     * 设置取消监听器集合
     */
    private fun setOnCancelListeners(listeners: MutableList<OnCancelListener?>?) {
        super.setOnCancelListener(mListeners)
        mCancelListeners = listeners
    }

    /**
     * 设置销毁监听器集合
     */
    private fun setOnDismissListeners(listeners: MutableList<OnDismissListener?>?) {
        super.setOnDismissListener(mListeners)
        mDismissListeners = listeners
    }

    /**
     * [DialogInterface.OnShowListener]
     */
    override fun onShow(dialog: DialogInterface) {
        mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_RESUME)
        if (mShowListeners != null) {
            for (i in mShowListeners!!.indices.reversed()) {
                mShowListeners!![i]?.onShow(this)
            }
        }
    }

    /**
     * [DialogInterface.OnCancelListener]
     */
    override fun onCancel(dialog: DialogInterface) {
        if (mCancelListeners != null) {
            for (i in mCancelListeners!!.indices.reversed()) {
                mCancelListeners!![i]?.onCancel(this)
            }
        }
    }

    /**
     * [DialogInterface.OnDismissListener]
     */
    override fun onDismiss(dialog: DialogInterface) {
        mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY)
        if (mDismissListeners != null) {
            for (i in mDismissListeners!!.indices.reversed()) {
                mDismissListeners!![i]?.onDismiss(this)
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_CREATE)
    }

    override fun onStart() {
        super.onStart()
        mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_START)
    }

    override fun onStop() {
        super.onStop()
        mLifecycle.handleLifecycleEvent(Lifecycle.Event.ON_STOP)
    }

    open class Builder<B : Builder<B>>(private val mContext: Context) : LifecycleOwner,
        ActivityAction,
        ResourcesAction, ClickAction {
        /**
         * 获取当前 Dialog 对象
         */
        /** Dialog 对象  */
        var dialog: BaseDialog? = null
            private set
        /**
         * 获取 Dialog 的根布局
         */
        /** Dialog 布局  */
        var contentView: View? = null
            private set

        /** 主题样式  */
        private var mThemeId = R.style.BaseDialogStyle

        /** 动画样式  */
        private var mAnimStyle: Int = AnimAction.Companion.ANIM_DEFAULT

        /** 重心位置  */
        private var mGravity = Gravity.NO_GRAVITY

        /** 水平偏移  */
        private var mXOffset = 0

        /** 垂直偏移  */
        private var mYOffset = 0

        /** 宽度和高度  */
        private var mWidth = ViewGroup.LayoutParams.WRAP_CONTENT
        private var mHeight = ViewGroup.LayoutParams.WRAP_CONTENT

        /** 背景遮盖层开关  */
        private var mBackgroundDimEnabled = true

        /** 背景遮盖层透明度  */
        private var mBackgroundDimAmount = 0.5f

        /** 是否能够被取消  */
        private var mCancelable = true

        /** 点击空白是否能够取消  前提是这个对话框可以被取消  */
        private var mCanceledOnTouchOutside = true

        /** Dialog Show 监听  */
        private var mOnShowListeners: MutableList<OnShowListener?>? = null

        /** Dialog Cancel 监听  */
        private var mOnCancelListeners: MutableList<OnCancelListener?>? = null

        /** Dialog Dismiss 监听  */
        private var mOnDismissListeners: MutableList<OnDismissListener?>? = null

        /** Dialog Key 监听  */
        private var mOnKeyListener: OnKeyListener? = null

        /** 点击事件集合  */
        private var mClickArray: SparseArray<OnClickListener>? = null

        constructor(activity: Activity) : this(activity as Context) {}

        /**
         * 设置主题 id
         */
        fun setThemeStyle(@StyleRes id: Int): B {
            check(!isCreated) {
                // Dialog 创建之后不能再设置主题 id
                "are you ok?"
            }
            mThemeId = id
            return this as B
        }
        fun getContext(): Context {
            return mContext
        }
        /**
         * 设置布局
         */
        fun setContentView(@LayoutRes id: Int): B {
            // 这里解释一下，为什么要传 new FrameLayout，因为如果不传的话，XML 的根布局获取到的 LayoutParams 对象会为空，也就会导致宽高参数解析不出来
            return setContentView(
                LayoutInflater.from(mContext).inflate(id, FrameLayout(mContext), false)
            )
        }

        fun setContentView(view: View): B {
            contentView = view
            if (isCreated) {
                dialog?.setContentView(view)
            } else {
                val layoutParams = view.layoutParams
                if (layoutParams != null && mWidth == ViewGroup.LayoutParams.WRAP_CONTENT && mHeight == ViewGroup.LayoutParams.WRAP_CONTENT) {
                    // 如果当前 Dialog 的宽高设置了自适应，就以布局中设置的宽高为主
                    setWidth(layoutParams.width)
                    setHeight(layoutParams.height)
                }

                // 如果当前没有设置重心，就自动获取布局重心
                if (mGravity == Gravity.NO_GRAVITY) {
                    if (layoutParams is FrameLayout.LayoutParams) {
                        setGravity(layoutParams.gravity)
                    } else if (layoutParams is LinearLayout.LayoutParams) {
                        setGravity(layoutParams.gravity)
                    } else {
                        // 默认重心是居中
                        setGravity(Gravity.CENTER)
                    }
                }
            }
            return this as B
        }

        /**
         * 设置重心位置
         */
        open fun setGravity(gravity: Int): B {
            // 适配 Android 4.2 新特性，布局反方向（开发者选项 - 强制使用从右到左的布局方向）
            mGravity = gravity
            if (isCreated) {
                dialog?.gravity = gravity
            }
            return this as B
        }

        /**
         * 设置水平偏移
         */
        fun setXOffset(offset: Int): B {
            mXOffset = offset
            return this as B
        }

        /**
         * 设置垂直偏移
         */
        fun setYOffset(offset: Int): B {
            mYOffset = offset
            return this as B
        }

        /**
         * 设置宽度
         */
        fun setWidth(width: Int): B {
            mWidth = width
            if (isCreated) {
                dialog?.setWidth(width)
            } else {
                val params = if (contentView != null) contentView!!.layoutParams else null
                if (params != null) {
                    params.width = width
                    contentView!!.layoutParams = params
                }
            }
            return this as B
        }

        /**
         * 设置高度
         */
        fun setHeight(height: Int): B {
            mHeight = height
            if (isCreated) {
                dialog?.setHeight(height)
            } else {
                // 这里解释一下为什么要重新设置 LayoutParams
                // 因为如果不这样设置的话，第一次显示的时候会按照 Dialog 宽高显示
                // 但是 Layout 内容变更之后就不会按照之前的设置宽高来显示
                // 所以这里我们需要对 View 的 LayoutParams 也进行设置
                val params = if (contentView != null) contentView!!.layoutParams else null
                if (params != null) {
                    params.height = height
                    contentView!!.layoutParams = params
                }
            }
            return this as B
        }

        /**
         * 是否可以取消
         */
        fun setCancelable(cancelable: Boolean): B {
            mCancelable = cancelable
            if (isCreated) {
                dialog?.setCancelable(cancelable)
            }
            return this as B
        }

        /**
         * 是否可以通过点击空白区域取消
         */
        fun setCanceledOnTouchOutside(cancel: Boolean): B {
            mCanceledOnTouchOutside = cancel
            if (isCreated && mCancelable) {
                dialog?.setCanceledOnTouchOutside(cancel)
            }
            return this as B
        }

        /**
         * 设置动画，已经封装好几种样式，具体可见[AnimAction]类
         */
        fun setAnimStyle(@StyleRes id: Int): B {
            mAnimStyle = id
            if (isCreated) {
                dialog?.windowAnimations = id
            }
            return this as B
        }

        /**
         * 设置背景遮盖层开关
         */
        fun setBackgroundDimEnabled(enabled: Boolean): B {
            mBackgroundDimEnabled = enabled
            if (isCreated) {
                dialog?.setBackgroundDimEnabled(enabled)
            }
            return this as B
        }

        /**
         * 设置背景遮盖层的透明度（前提条件是背景遮盖层开关必须是为开启状态）
         */
        fun setBackgroundDimAmount(@FloatRange(from = 0.0, to = 1.0) dimAmount: Float): B {
            mBackgroundDimAmount = dimAmount
            if (isCreated) {
                dialog?.setBackgroundDimAmount(dimAmount)
            }
            return this as B
        }

        /**
         * 添加显示监听
         */
        fun addOnShowListener(listener: OnShowListener): B {
            if (isCreated) {
                dialog?.addOnShowListener(listener)
            } else {
                if (mOnShowListeners == null) {
                    mOnShowListeners = ArrayList()
                }
                mOnShowListeners!!.add(listener)
            }
            return this as B
        }

        /**
         * 添加取消监听
         */
        fun addOnCancelListener(listener: OnCancelListener): B {
            if (isCreated) {
                dialog?.addOnCancelListener(listener)
            } else {
                if (mOnCancelListeners == null) {
                    mOnCancelListeners = ArrayList()
                }
                mOnCancelListeners!!.add(listener)
            }
            return this as B
        }

        /**
         * 添加销毁监听
         */
        fun addOnDismissListener(listener: OnDismissListener): B {
            if (isCreated) {
                dialog?.addOnDismissListener(listener)
            } else {
                if (mOnDismissListeners == null) {
                    mOnDismissListeners = ArrayList()
                }
                mOnDismissListeners!!.add(listener)
            }
            return this as B
        }

        /**
         * 设置按键监听
         */
        fun setOnKeyListener(listener: OnKeyListener): B {
            if (isCreated) {
                dialog?.setOnKeyListener(listener)
            } else {
                mOnKeyListener = listener
            }
            return this as B
        }

        /**
         * 设置文本
         */
        fun setText(@IdRes viewId: Int, @StringRes stringId: Int): B {
            return setText(viewId, getString(stringId))
        }

        fun setText(@IdRes id: Int, text: CharSequence?): B {
            (findViewById(id) as TextView).text = text
            return this as B
        }

        /**
         * 设置文本颜色
         */
        fun setTextColor(@IdRes id: Int, @ColorInt color: Int): B {
            (findViewById(id) as TextView).setTextColor(color)
            return this as B
        }

        /**
         * 设置提示
         */
        fun setHint(@IdRes viewId: Int, @StringRes stringId: Int): B {
            return setHint(viewId, getString(stringId))
        }

        fun setHint(@IdRes id: Int, text: CharSequence?): B {
            (findViewById(id) as TextView).hint = text
            return this as B
        }

        /**
         * 设置可见状态
         */
        fun setVisibility(@IdRes id: Int, visibility: Int): B {
            findViewById<View>(id).visibility = visibility
            return this as B
        }

        /**
         * 设置背景
         */
        fun setBackground(@IdRes viewId: Int, @DrawableRes drawableId: Int): B {
            return setBackground(viewId, ContextCompat.getDrawable(mContext, drawableId))
        }

        fun setBackground(@IdRes id: Int, drawable: Drawable?): B {
            findViewById<View>(id).background = drawable
            return this as B
        }

        /**
         * 设置图片
         */
        fun setImageDrawable(@IdRes viewId: Int, @DrawableRes drawableId: Int): B {
            return setBackground(viewId, ContextCompat.getDrawable(mContext, drawableId))
        }

        fun setImageDrawable(@IdRes id: Int, drawable: Drawable?): B {
            (findViewById(id) as ImageView).setImageDrawable(drawable)
            return this as B
        }

        /**
         * 设置点击事件
         */
        fun setOnClickListener(@IdRes id: Int, listener: OnClickListener): B {
            if (isCreated) {
                val view = findViewById<View>(id)
                view.setOnClickListener(ViewClickWrapper(dialog!!, listener))
            } else {
                if (mClickArray == null) {
                    mClickArray = SparseArray()
                }
                mClickArray!!.put(id, listener)
            }
            return this as B
        }

        /**
         * 创建
         */
        @SuppressLint("RtlHardcoded")
        open fun create(): BaseDialog {

            // 判断布局是否为空
            if (contentView == null) {
                throw IllegalArgumentException("are you ok?")
            }

            // 如果当前没有设置重心，就设置一个默认的重心
            if (mGravity == Gravity.NO_GRAVITY) {
                mGravity = Gravity.CENTER
            }

            // 如果当前没有设置动画效果，就设置一个默认的动画效果
            if (mAnimStyle == AnimAction.Companion.ANIM_DEFAULT) {
                mAnimStyle = when (mGravity) {
                    Gravity.TOP -> AnimAction.Companion.ANIM_TOP
                    Gravity.BOTTOM -> AnimAction.Companion.ANIM_BOTTOM
                    Gravity.LEFT -> AnimAction.Companion.ANIM_LEFT
                    Gravity.RIGHT -> AnimAction.Companion.ANIM_RIGHT
                    else -> AnimAction.Companion.ANIM_DEFAULT
                }
            }
            dialog = createDialog(mContext, mThemeId)
            dialog?.setContentView(contentView!!)
            dialog?.setCancelable(mCancelable)
            if (mCancelable) {
                dialog?.setCanceledOnTouchOutside(mCanceledOnTouchOutside)
            }

            // 设置参数
            val window = dialog?.window
            if (window != null) {
                val params = window.attributes
                params.width = mWidth
                params.height = mHeight
                params.gravity = mGravity
                params.x = mXOffset
                params.y = mYOffset
                params.windowAnimations = mAnimStyle
                window.attributes = params
                if (mBackgroundDimEnabled) {
                    window.addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
                    window.setDimAmount(mBackgroundDimAmount)
                } else {
                    window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND)
                }
            }
            if (mOnShowListeners != null) {
                dialog?.setOnShowListeners(mOnShowListeners)
            }
            if (mOnCancelListeners != null) {
                dialog?.setOnCancelListeners(mOnCancelListeners)
            }
            if (mOnDismissListeners != null) {
                dialog?.setOnDismissListeners(mOnDismissListeners)
            }
            if (mOnKeyListener != null) {
                dialog?.setOnKeyListener(mOnKeyListener)
            }
            var i = 0
            while (mClickArray != null && i < mClickArray!!.size()) {
                contentView!!.findViewById<View>(mClickArray!!.keyAt(i)).setOnClickListener(
                    ViewClickWrapper(
                        dialog!!, mClickArray!!.valueAt(i)
                    )
                )
                i++
            }
            val activity = activity
            if (activity != null) {
                DialogLifecycle.with(activity, dialog!!)
            }
            return dialog!!
        }

        /**
         * 显示
         */
        open fun show(): BaseDialog {
            if (!isCreated) {
                create()
            }
            dialog?.show()
            return dialog!!
        }

        /**
         * 销毁当前 Dialog
         */
        fun dismiss() {
            dialog?.dismiss()
        }

        override val myContext: Context
            get() = mContext

        /**
         * 当前 Dialog 是否创建了
         */
        val isCreated: Boolean
            get() = dialog != null

        /**
         * 当前 Dialog 是否显示了
         */
        val isShowing: Boolean
            get() = dialog?.isShowing ?: false

        /**
         * 创建 Dialog 对象（子类可以重写此方法来改变 Dialog 类型）
         */
        protected fun createDialog(context: Context, @StyleRes themeId: Int): BaseDialog {
            return BaseDialog(context, themeId)
        }

        /**
         * 延迟执行
         */
        fun post(r: Runnable?) {
            if (isShowing) {
                dialog?.post(r)
            } else {
                addOnShowListener(ShowPostWrapper(r))
            }
        }

        /**
         * 延迟一段时间执行
         */
        fun postDelayed(r: Runnable?, delayMillis: Long) {
            if (isShowing) {
                dialog?.postDelayed(r, delayMillis)
            } else {
                addOnShowListener(ShowPostDelayedWrapper(r, delayMillis))
            }
        }

        /**
         * 在指定的时间执行
         */
        fun postAtTime(r: Runnable?, uptimeMillis: Long) {
            if (isShowing) {
                dialog?.postAtTime(r, uptimeMillis)
            } else {
                addOnShowListener(ShowPostAtTimeWrapper(r, uptimeMillis))
            }
        }

        /**
         * 根据 id 查找 View
         */
        final override fun <V : View> findViewById(@IdRes id: Int): V {
            if (contentView == null) {
                // 没有 setContentView 就想 findViewById ?
                throw IllegalStateException("are you ok?")
            }
            return contentView!!.findViewById(id)
        }

        override fun getLifecycle(): Lifecycle {
            return dialog!!.lifecycle
        }


    }

    /**
     * Dialog 生命周期管理
     */
    private class DialogLifecycle private constructor(activity: Activity, dialog: BaseDialog) :
        Application.ActivityLifecycleCallbacks, OnShowListener, OnDismissListener {
        private var mDialog: BaseDialog? = null
        private var mActivity: Activity?

        /** Dialog 动画样式（避免 Dialog 从后台返回到前台后再次触发动画效果）  */
        private var mDialogAnim = 0
        override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
        override fun onActivityStarted(activity: Activity) {}
        override fun onActivityResumed(activity: Activity) {
            if (mActivity !== activity) {
                return
            }
            if (mDialog != null && mDialog!!.isShowing) {
                // 还原 Dialog 动画样式（这里必须要使用延迟设置，否则还是有一定几率会出现）
                mDialog!!.postDelayed({
                    if (mDialog != null && mDialog!!.isShowing()) {
                        mDialog!!.windowAnimations = mDialogAnim
                    }
                }, 100)
            }
        }

        override fun onActivityPaused(activity: Activity) {
            if (mActivity !== activity) {
                return
            }
            if (mDialog != null && mDialog!!.isShowing) {
                // 获取 Dialog 动画样式
                mDialogAnim = mDialog!!.windowAnimations
                // 设置 Dialog 无动画效果
                mDialog!!.windowAnimations = AnimAction.Companion.ANIM_EMPTY
            }
        }

        override fun onActivityStopped(activity: Activity) {}
        override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
        override fun onActivityDestroyed(activity: Activity) {
            if (mActivity !== activity) {
                return
            }
            if (mDialog != null) {
                mDialog!!.removeOnShowListener(this)
                mDialog!!.removeOnDismissListener(this)
                if (mDialog!!.isShowing) {
                    mDialog!!.dismiss()
                }
                mDialog = null
            }
            unregisterActivityLifecycleCallbacks()
            // 释放 Activity 对象
            mActivity = null
        }

        override fun onShow(dialog: BaseDialog) {
            mDialog = dialog
            registerActivityLifecycleCallbacks()
        }

        override fun onDismiss(dialog: BaseDialog?) {
            mDialog = null
            unregisterActivityLifecycleCallbacks()
        }

        /**
         * 注册 Activity 生命周期监听
         */
        private fun registerActivityLifecycleCallbacks() {
            if (mActivity == null) {
                return
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                mActivity!!.registerActivityLifecycleCallbacks(this)
            } else {
                mActivity!!.application.registerActivityLifecycleCallbacks(this)
            }
        }

        /**
         * 反注册 Activity 生命周期监听
         */
        private fun unregisterActivityLifecycleCallbacks() {
            if (mActivity == null) {
                return
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                mActivity!!.unregisterActivityLifecycleCallbacks(this)
            } else {
                mActivity!!.application.unregisterActivityLifecycleCallbacks(this)
            }
        }

        companion object {
            fun with(activity: Activity, dialog: BaseDialog) {
                DialogLifecycle(activity, dialog)
            }
        }

        init {
            mActivity = activity
            dialog.addOnShowListener(this)
            dialog.addOnDismissListener(this)
        }
    }

    /**
     * Dialog 监听包装类（修复原生 Dialog 监听器对象导致的内存泄漏）
     */
    private class ListenersWrapper<T>(referent: T) : SoftReference<T>(referent),
        DialogInterface.OnShowListener, DialogInterface.OnCancelListener,
        DialogInterface.OnDismissListener where T : DialogInterface.OnShowListener, T : DialogInterface.OnCancelListener, T : DialogInterface.OnDismissListener {
        override fun onShow(dialog: DialogInterface) {
            get()?.onShow(dialog)
        }

        override fun onCancel(dialog: DialogInterface) {
            get()?.onCancel(dialog)
        }

        override fun onDismiss(dialog: DialogInterface) {
            get()?.onDismiss(dialog)
        }
    }

    /**
     * 点击事件包装类
     */
    private class ViewClickWrapper(
        private val mDialog: BaseDialog,
        private val mListener: OnClickListener
    ) : View.OnClickListener {
        override fun onClick(v: View) {
            mListener.onClick(mDialog, v)
        }
    }

    /**
     * 显示监听包装类
     */
    private class ShowListenerWrapper(referent: DialogInterface.OnShowListener) :
        SoftReference<DialogInterface.OnShowListener?>(referent), OnShowListener {
        override fun onShow(dialog: BaseDialog) {
            // 在横竖屏切换后监听对象会为空
            if (get() != null) {
                get()!!.onShow(dialog)
            }
        }
    }

    /**
     * 取消监听包装类
     */
    private class CancelListenerWrapper(referent: DialogInterface.OnCancelListener) :
        SoftReference<DialogInterface.OnCancelListener?>(referent), OnCancelListener {
        override fun onCancel(dialog: BaseDialog?) {
            // 在横竖屏切换后监听对象会为空
            if (get() != null) {
                get()!!.onCancel(dialog)
            }
        }
    }

    /**
     * 销毁监听包装类
     */
    private class DismissListenerWrapper(referent: DialogInterface.OnDismissListener) :
        SoftReference<DialogInterface.OnDismissListener?>(referent), OnDismissListener {
        override fun onDismiss(dialog: BaseDialog?) {
            // 在横竖屏切换后监听对象会为空
            if (get() != null) {
                get()!!.onDismiss(dialog)
            }
        }
    }

    /**
     * 按键监听包装类
     */
    private class KeyListenerWrapper(private val mListener: OnKeyListener?) :
        DialogInterface.OnKeyListener {
        override fun onKey(dialog: DialogInterface, keyCode: Int, event: KeyEvent): Boolean {
            // 在横竖屏切换后监听对象会为空
            if (mListener != null && dialog is BaseDialog) {
                mListener.onKey(dialog, event)
            }
            return false
        }
    }

    /**
     * post 任务包装类
     */
    private class ShowPostWrapper(private val mRunnable: Runnable?) : OnShowListener {
        override fun onShow(dialog: BaseDialog) {
            if (mRunnable != null) {
                dialog.removeOnShowListener(this)
                dialog.post(mRunnable)
            }
        }
    }

    /**
     * postDelayed 任务包装类
     */
    private class ShowPostDelayedWrapper(
        private val mRunnable: Runnable?,
        private val mDelayMillis: Long
    ) : OnShowListener {
        override fun onShow(dialog: BaseDialog) {
            if (mRunnable != null) {
                dialog.removeOnShowListener(this)
                dialog.postDelayed(mRunnable, mDelayMillis)
            }
        }
    }

    /**
     * postAtTime 任务包装类
     */
    private class ShowPostAtTimeWrapper(
        private val mRunnable: Runnable?,
        private val mUptimeMillis: Long
    ) : OnShowListener {
        override fun onShow(dialog: BaseDialog) {
            if (mRunnable != null) {
                dialog.removeOnShowListener(this)
                dialog.postAtTime(mRunnable, mUptimeMillis)
            }
        }
    }

    /**
     * 点击监听器
     */
    interface OnClickListener {
        fun onClick(dialog: BaseDialog, view: View)
    }

    /**
     * 显示监听器
     */
    interface OnShowListener {
        /**
         * Dialog 显示了
         */
        fun onShow(dialog: BaseDialog)
    }

    /**
     * 取消监听器
     */
    interface OnCancelListener {
        /**
         * Dialog 取消了
         */
        fun onCancel(dialog: BaseDialog?)
    }

    /**
     * 销毁监听器
     */
    interface OnDismissListener {
        /**
         * Dialog 销毁了
         */
        fun onDismiss(dialog: BaseDialog?)
    }

    /**
     * 按键监听器
     */
    interface OnKeyListener {
        /**
         * 触发了按键
         */
        fun onKey(dialog: BaseDialog?, event: KeyEvent?): Boolean
    }
}